<template>
    <vxe-modal v-model="dialogVisible" :loading="uploadLoading" title="请选择文件夹" width="1000" :zIndex="2000" destroy-on-close :show-close="true" @close="closeVisible">
        <template v-slot>
            <el-upload ref="encryptionUpLoad"
                       action="uploadUrl"
                       :show-file-list="false"
                       :multiple="true"
                       :on-change="handleChange"
                       :auto-upload="false"
                       :http-request="httpRequest"
                       :file-list="uploadFiles"
                       :accept="acceptType"
                       :on-exceed="fileExceed">
                <el-button slot="trigger" size="mini" :disabled="isSelectFolder" type="primary">选择文件夹</el-button>
                <el-button style="margin-left: 10px;" size="mini" :disabled="uploadFiles.length == 0" type="success" @click="submitUpload2(0)">上传到服务器</el-button>
            </el-upload>
            <el-table :data="uploadFilesList" style="width: 100%" row-key="uid" :default-expand-all="true" height="450" :tree-props="{children: 'children', hasChildren: 'hasChildren'}">
                <el-table-column prop="name" :show-overflow-tooltip="true" label="名称" width="320">
                    <template slot-scope="scope">
                        <i style="color:#409EFF" class=" el-icon-s-order" />
                        {{ scope.row.name }}
                    </template>
                </el-table-column>
                <el-table-column prop="name" label="是否成功" width="140">
                    <template slot-scope="scope">
                        <template v-if="scope.row.status==='success'">
                            <div style="color:green">上传成功！</div>
                        </template>
                        <template v-else-if="scope.row.status != 'success' && scope.row.status != 'uploading'">
                            <div style="color:red">{{ scope.row.status }}</div>
                        </template>
                        <el-progress v-else :percentage="scope.row.progress" />
                    </template>
                </el-table-column>
                <el-table-column width="100" prop="size" label="文件大小" />
                <el-table-column prop="name" width="150" :show-overflow-tooltip="true" label="密级">
                    <template slot-scope="scope">
                        <el-select v-model="scope.row.securityLevel" :disabled="scope.row.status==='success'" placeholder="请选择" :popper-append-to-body="false" @change="selectSecurityLevel(scope.row)">
                            <el-option v-for="item in mjOptions"
                                       :key="item.value"
                                       :label="item.label"
                                       :value="item.value">
                            </el-option>
                        </el-select>
                    </template>
                </el-table-column>
                <el-table-column prop="name" width="150" :show-overflow-tooltip="true" label="保密期限">
                    <template slot-scope="scope">
                        <el-input size="small" type="number" min="0" :disabled="scope.row.status==='success'" v-model="scope.row.securityPeriod" placeholder="请输入">
                            <i slot="suffix" style="font-style:normal;margin-right: 10px; line-height: 30px; color: #1e1e1e">(年)</i>
                        </el-input>
                    </template>
                </el-table-column>
                <el-table-column prop="name" width="100" :show-overflow-tooltip="true" label="功能">
                    <template slot-scope="scope">
                        <el-button type="primary" size="mini" :disabled="scope.row.status === 'success'" @click="handleRemove(scope.row)">删除</el-button>
                    </template>
                </el-table-column>
            </el-table>
            <div class="size14">注意：一次性选取多个文件时,请先等待读取文件,请勿关闭此页面</div>
            <div class="modal_footer">
                <vxe-button status="primary" content="关 闭" size="small" @click="closeVisible" />
            </div>
            <div style="color:orange;" v-if="showPercent">上传过程请勿刷新浏览器和跳转其他页面...</div>
            <!-- 进度条 -->
            <el-progress v-if="showPercent" :percentage="Number((index*100/percentTotal).toFixed(0))"></el-progress>
        </template>
    </vxe-modal>
</template>

<script>
    import supplierContactsAPI from "../../request/MaintData/SupplierContactsAPI.js";
    import supplierAPI from "../../request/MaintData/SupplierAPI.js";
    import { getUserSeclevel } from '../../request/Security/Login.js';
    import currencyJson from '../../common/json/currency.js'
    import shipFileAPI from '../../request/MaintData/ShipTypeFileAPI.js';
    import folderUpLoadAPI from '../../request/ShipArchives/FolderUpLoadAPI.js';
    export default {
        components: {
        },
        props: {
            isMultiple: { type: Boolean, default: false },
            limit: { type: Number, default: 100 },
            fatherID: { type: Object, default: null },
            fileTypeInfo: { type: Number, default: null },
            uploadUrl: { type: Object, default: null },
            isCountRows: { type: Boolean, default: false },
            nowSelectDir: { type: Array, default: [] },
            nowSelectShip: { type: Object, default: null },
            nowSelected: { type: Object, default: null },
            formInfo: { type: Object, default: null },
            shipFileType: { type: Boolean, default: true },
        },
        data() {
            return {
                currencyJson,
                dialogVisible: false,
                fileList: [],
                uploadFilesList: [],
                uploadFiles: [],
                securityLevel: null,
                mjOptions: [],
                securityPeriod: null,
                uploadLoading: false,
                acceptType: '',
                isSelectFolder: false,
                catalogArr: [],
                treeList: [],
                promiseList: [],
                timeEnd: null,
                num: 0,
                index: 0,
                percentTotal: 0,
                showPercent:false
            };
        },
        mounted() {
            var _this = this;
            this.num = 0;
            this.timeEnd = this.debounce(this.debounce2, 50);
            window.onresize = () => {
                return (() => {
                    _this.tableH = window.innerHeight - topBarHeight - 80;
                })();
            };
        },
        beforeDestroy() {
            window.onresize = null;
        },
        methods: {
            async show() {
                this.isCountRows === true ? this.acceptType = '.xls,.xlsx' : this.acceptType = '';
                var mj = await this.getUserSeclevelList();
                this.mjOptions = mj ? this.currencyJson.mjOptions.filter(e => e.value <= Number(mj)) : [];
                this.dialogVisible = true;
                this.$nextTick(() => {
                    var x = document.getElementsByClassName("el-upload__input");
                    x[0].webkitdirectory = true;
                    x[1].webkitdirectory = true;
                    x[2].webkitdirectory = true;
                })
            },
            getUserSeclevelList() {
                return new Promise((resolve) => {
                    getUserSeclevel().then(res => {
                        console.log('getUserSeclevel', res);
                        resolve(res);
                    }).catch(() => {
                        resolve(undefined);
                    });
                });
            },
            
            handleChange(file, fileList) {
                this.num++;
                if (this.isCountRows) {
                    const files = file.raw;
                    const reader = new FileReader();
                    reader.readAsBinaryString(files);
                    reader.onload = ev => {
                        try {
                            const f = ev.target.result;
                            const workbook = XLSX.read(f, { type: "binary" });
                            const wsname = workbook.SheetNames[0]; //取到第一个Sheet页
                            const ws = XLSX.utils.sheet_to_json(workbook.Sheets[wsname], { header: 1, defval: '#' });
                            //至此，将拿到excel工作簿中的数据，下面就可以自己操作了
                            //........
                            this.$confirm(`当前文件共有 ${ws.length}行数据,是否继续上传?`, '提示', {
                                confirmButtonText: '确定',
                                cancelButtonText: '取消',
                                type: 'warning'
                            }).then(() => {
                                const fileList22 = {};
                                for (const key in file) {
                                    fileList22[key] = file[key]
                                };
                                // status:uploading、success、error 文件上传状态
                                // progress 文件上传进度
                                var name = fileList22.name;
                                var securityLevel = name.indexOf('非密') != -1 ? 1 :
                                    name.indexOf('内部') != -1 ? 2 :
                                        name.indexOf('MM') != -1 ? 3 :
                                            name.indexOf('JM') != -1 ? 4 :
                                                name.indexOf('JM') != -1 ? null : 1;
                                var securityPeriod = name.indexOf('非密') != -1 ? 0 :
                                    name.indexOf('内部') != -1 ? 0 :
                                        name.indexOf('MM') != -1 ? 10 :
                                            name.indexOf('JM') != -1 ? 20 :
                                                name.indexOf('JM') != -1 ? null : null;
                                if (securityLevel > this.userMj) {
                                    securityLevel = null;
                                    securityPeriod = null
                                };
                                this.uploadFilesList.push({ ...fileList22, progress: 0, status: 'uploading', securityLevel: securityLevel, securityPeriod: securityPeriod });
                                this.uploadFiles = fileList;
                            }).catch(() => {
                                console.log(this.uploadFiles)
                            })
                        }
                        catch (e) {
                            console.log(e);
                            return false;
                        }
                    };
                } else {
                    const fileList22 = {};
                    for (const key in file) {
                        fileList22[key] = file[key]
                    };
                    // status:uploading、success、error 文件上传状态
                    // progress 文件上传进度
                    var name = fileList22.name;
                    var securityLevel = name.indexOf('非密') != -1 ? 1 :
                        name.indexOf('内部') != -1 ? 2 :
                            name.indexOf('MM') != -1 ? 3 :
                                name.indexOf('JM') != -1 ? 4 :
                                    name.indexOf('JM') != -1 ? null : 1;
                    var securityPeriod = name.indexOf('非密') != -1 ? 0 :
                        name.indexOf('内部') != -1 ? 0 :
                            name.indexOf('MM') != -1 ? 10 :
                                name.indexOf('JM') != -1 ? 20 :
                                    name.indexOf('JM') != -1 ? 0 : 0;
                    if (securityLevel > this.userMj) {
                        securityLevel = null;
                        securityPeriod = null
                    };
                    var filePath = fileList22.raw.webkitRelativePath;
                    this.uploadFilesList.push({ ...fileList22, progress: 0, status: 'uploading', securityLevel: securityLevel, securityPeriod: securityPeriod, filePath: filePath });
                    this.uploadFiles = fileList;
                    this.isSelectFolder = true;
                    //this.treeList = this.createTreeFromPaths(fileList);
                };
                this.percentTotal = this.uploadFilesList.length;
                this.timeEnd(this.num);
            },
            
            //防抖
            debounce(fn, delay) {
                let timer;
                return function () {
                    if (timer) {
                        clearTimeout(timer);
                    }
                    timer = setTimeout(() => {
                        fn();
                    }, delay);
                }
            },
            debounce2() {
                this.uploadLoading = false;
                this.$message({ type: 'success', message: `已从所选文件夹中读取${this.num}个文件` });
            },
            //根据文件路径处理数据
            pathArrToTree(arr) {
                let treeDTO = []
                arr.forEach(item => {
                    const nodeArray = item.raw.webkitRelativePath.split('/');
                    let children = treeDTO
                    for (const i of nodeArray) {// 循环构建子节点
                        const node = {
                            name: i,
                            isDir: item.name === i ? false : true,
                            id: this.randomNum(6),
                            parentID: null,
                            uid: item.uid
                        };
                        if (!children.length === 0) children.push(node);
                        let isExist = false;
                        for (const j in children) {
                            if (children[j].name === node.name) {
                                if (!children[j].children) {
                                    children[j].children = []
                                };
                                children = children[j].children;
                                isExist = true;
                                break;
                            }
                        }
                        if (!isExist) {
                            children.push(node);
                            if (!children[children.length - 1].children) {
                                children[children.length - 1].children = [];
                            }
                            children = children[children.length - 1].children;
                        }
                    }
                })
                return treeDTO;
            },
            submitUpload2() {
                if (this.uploadFilesList.findIndex(x => x.securityLevel === null) > -1) {
                    this.$message({ type: 'warning', message: '请先设置文件密级!' });
                    return;
                };
                const ids = this.uploadFilesList.map(value => value.name);
                const idsSet = new Set(ids);
                //if (idsSet.size !== ids.length) {
                //    this.$message({ type: 'warning', message: '文件名重复!' });
                //    return;
                //};
                this.uploadLoading = true;
                this.showPercent = true;
                if (this.uploadFilesList.length > this.index) {
                    var x = this.uploadFilesList[this.index];
                    var obj = {};
                    var dirInfo = this.nowSelectDir[this.nowSelectDir.length - 1];
                   
                    obj = {
                        id: dirInfo ? dirInfo.id : null,
                        shipid: this.shipFileType?this.nowSelectShip.shipID:'0',
                        smodelid: this.shipFileType?'0':this.nowSelectShip.sModelID,
                        securityLevel: x.securityLevel,
                        securityPeriod: Number(x.securityPeriod),
                        filepath: x.filePath.replaceAll('/', '%2F').replaceAll('#', '%23'),
                    };
                    let _vm = this
                    let formData = new FormData()
                    formData.append('filename', x.raw)
                    let progress = 0;
                    axios.post(this.uploadUrl + JSON.stringify(obj), formData, {
                        headers: { 'content-type': 'multipart/form-data', 'Authorization': sessionStorage.getItem('token') }
                    })
                        .then(res2 => {
                            this.index++;
                            console.log('上传返回', this.index, this.percentTotal)
                            if (res2.status === 200) {
                                var parms = {
                                    progress, status: 'success'
                                };
                                this.showProgress(x, parms);
                                this.submitUpload2()
                               
                            } else {
                                var parms = {
                                    progress, status: '错误'
                                };
                                this.showProgress(x, parms);
                                this.submitUpload2()
                            }
                        })
                        .catch(err => {
                            var parms = {
                                progress, status: err.response ? err.response.data : '上传失败!'
                            };
                            this.showProgress(x, parms);

                            // 进行递归 上传下一个
                            this.index++;
                            this.submitUpload2()
                        })

                } else {
                    this.index = 0;
                    this.showPercent = false;
                    this.uploadLoading = false;
                    this.percentTotal = 0;
                    this.$refs.encryptionUpLoad.clearFiles();
                    this.uploadFiles = [];
                    //loadingFullScreen.close();
                    this.$message({ type: 'success', message: '文件夹上传完成!' });
                    return false
                }

            },
            //创建文件夹/文件
            async createTreeFromPaths(data) {
                //检查文件夹名称是否与当前所在节点内其他文件夹重复
                var dirInfo = this.nowSelectDir[this.nowSelectDir.length - 1];
                var fileExsit = await this.checkShipDevFileExsit({
                    fileName: data[0].name,//data[0]就是要上传的最外层文件夹,保证这个与同级文件夹不重复即可
                    shipid: this.nowSelectShip.shipID,
                    parentid: dirInfo ? dirInfo.id : null,
                    isDir: true
                });
                if (fileExsit) {
                    this.$message({ type: 'warning', message: '与当前目录下文件夹名称重复,请修改后再次上传!' });
                    return;
                } else {
                    console.log(this.uploadFilesList);
                    this.$refs.encryptionUpLoad.submit();
                    this.$refs.encryptionUpLoad.clearFiles();
                    this.uploadFiles = [];
                // 前端创建文件夹,这里弃用,更改为上传文件,后端根据文件路径创建文件夹
                //    let loadingFullScreen = this.$loading({
                //        lock: true,
                //        text: '正在创建文件夹',
                //        spinner: 'el-icon-loading',
                //        background: 'rgba(0, 0, 0, 0.6)'
                //    });
                //    await this.createCheckByTree(data, {}).then(() => {
                //            Promise.all(this.promiseList).then(() => {
                //                    loadingFullScreen.close();
                //                    this.uploadFile(data);
                //                })
                //        });
                };
            },
            uploadFile() {
                this.$refs.encryptionUpLoad.submit();
                this.$refs.encryptionUpLoad.clearFiles();
                this.uploadFiles = [];
            },
            // 递归 创建文件夹
            createCheckByTree(treeList, formInfo = {}) {
                return new Promise((resolve) => {
                    var dirInfo = this.nowSelectDir[this.nowSelectDir.length - 1];
                    for (let item of treeList) {
                        if (item.isDir) {
                            var info = {
                                fileName: item.name,
                                isDir: item.isDir,
                                shipID: this.nowSelectShip.shipID,
                                parentID: formInfo.sdfid ? formInfo.sdfid :
                                    dirInfo ? dirInfo.id : null,
                                parentName: formInfo.sdfid ? formInfo.fileName :
                                    dirInfo ? dirInfo.name : null,
                                securityLevel: 0
                            };
                            this.promiseList.push(this.createCheck(info, item.children));
                        } else {
                            this.uploadFilesList.find(x => x.uid === item.uid).parentID = formInfo.sdfid;
                        };
                    };
                    resolve();
                })
            },
            //检查文件夹名称是否重复
            checkShipDevFileExsit(params) {
                return new Promise(resolve => {
                    folderUpLoadAPI[this.nowSelected.checkFileExsitUrl](params).then(res => {
                        if (res) {
                            this.$message({
                                type: 'warning',
                                message: `${params.isDir ? '文件夹名称' : '文件名'}重复，请确认或修改后重新上传`
                            });
                        }
                        resolve(res);
                    }).catch(() => {
                        this.$message({
                            type: 'warning',
                            message: `${params.isDir ? '文件夹名称' : '文件名'}重复，请确认或修改后重新上传`
                        });
                        resolve(true);
                    });
                });
            },
            //新建文件夹
            createCheck(data,item) {
                return new Promise((resolve) => {
                    var requestName = '';
                    requestName = data[this.nowSelected.id] ? this.nowSelected.updateUrl : this.nowSelected.createUrl;
                    folderUpLoadAPI[requestName](data).then(res => {
                        this.createCheckByTree(item, res)
                        resolve(res);
                    }).catch(() => {
                    });
                });
            },
            async httpRequest(row) {
                this.uploadLoading = true;
                var file = row.file;
                var securityLevel = this.uploadFilesList.find(x => x.uid === file.uid).securityLevel;
                var securityPeriod = this.uploadFilesList.find(x => x.uid === file.uid).securityPeriod;
                var filePath = this.uploadFilesList.find(x => x.uid === file.uid).filePath.replaceAll('/','%2F');
                var obj = {};
                var dirInfo = this.nowSelectDir[this.nowSelectDir.length - 1];
                obj = {
                    id: dirInfo ? dirInfo.id :null,
                    shipid: this.nowSelectShip.shipID,
                    securityLevel: securityLevel,
                    securityPeriod: Number(securityPeriod),
                    filepath: filePath
                };
                console.log(obj, this.uploadUrl);
                var form = new FormData();
                form.append('filename', file);
                let progress = 0;
                var imageUpload = params => {
                    return axios.post(this.uploadUrl + JSON.stringify(obj), params, {
                        headers: { 'content-type': 'multipart/form-data', 'Authorization': sessionStorage.getItem('token') }
                    })
                };
                imageUpload(form).then(res => {
                    var parms = {
                        progress, status: 'success'
                    };
                    this.uploadLoading = false;
                    this.showProgress(file, parms);
                }).catch(err => {
                    var parms = {
                        progress, status: err.response ? err.response.data : '上传失败!'
                    };
                    this.uploadLoading = false;
                    this.showProgress(file, parms);
                })
            },
            showProgress(file, parms) {
                const { progress, status } = parms;
                const arr = [...this.uploadFilesList].map(items => {
                    if (items.uid === file.uid) {
                        items.progress = progress;
                        items.status = status;
                    };
                    return items;
                })
                this.uploadFilesList = [...arr];
            },

            selectSecurityLevel(row) {
                row.securityLevel <= 2 ?
                    row.securityPeriod = 0 :
                    row.securityLevel === 3 ?
                        row.securityPeriod = 10 :
                        row.securityLevel === 4 ?
                            row.securityPeriod = 20 : ''
            },

            //生成n位数字字符串
            randomNum(n) {
                var res = "";
                for (var i = 0; i < n; i++) {
                    res += Math.floor(Math.random() * 10);
                }
                return res;
            },

            handleRemove(row) {
                this.uploadFilesList.splice(this.uploadFilesList.indexOf(row), 1);
                this.uploadFiles.splice(this.uploadFiles.indexOf(row), 1);
                this.uploadFilesList.length === 0 ? this.isSelectFolder = false : this.isSelectFolder = true;
                this.percentTotal = this.uploadFilesList.length;
            },
            closeVisible() {
                this.num = 0;
                this.$emit('uploadOver', this.uploadFilesList);
                this.uploadFilesList = [];
                this.uploadFiles = [];
                this.$refs.encryptionUpLoad.clearFiles();
                this.dialogVisible = false;
                this.isSelectFolder = false;
                //this.getFiles(0);
            },
            // 文件超出上传个数限制的钩子
            fileExceed(files, fileList) {
                this.$message({ type: 'warning', message: '超出文件上传单次个数限制!' });
            },
            format(ops, op, hasops) {
                var val = null;
                if (hasops) {
                    var options = ops
                        .map((e) => {
                            return e.options;
                        })
                        .flat()
                        .valueOf();
                    val = options.find((e) => e.value === op);
                } else {
                    val = ops.find((e) => e.value === op);
                }
                return val ? val.label : "";
            },
            toDate(date) {
                return date ? moment(date).format("YYYY-MM-DD HH:mm:ss") : "";
            },
        },
        template: "#template",
    };
</script>
